﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityFrameworkStudy.Studys
{
    class OneToManyRelationStudy
    {
        public static void 删除一对多关系的主模型()
        {
            /*
             * 以Article和Post为例，删除Article的步骤如下：
             * 
             * 1、将Article标记为已“经删除”。
             * 2、将内存中所有Article.Posts的Post.Article设置为null。
             * 2、将内存中所有Article.Posts的Post.ArticleId设置为null或保留不变（如果不是可空类型的话）。
             * 3、如果 配置了级联删除，将内存中所有Article.Posts标记为“已删除”。
             * 4、如果没有配置级联删除，将内存中所有Article.Posts标记为“已修改”。
             */
            using (var context = new StudyContext())
            {
                Console.WriteLine("\n配置级联删除，删除主键模型，外键模型自动删除。\n");

                var article1 = context.Articles.First(x => x.Title == "Title1");
                var post1 = context.Posts.First(x => x.Body == "Title1-Post");

                Console.WriteLine("Remove article1 之前");
                Console.WriteLine("post1.ArticleId：" + post1.ArticleId);
                Console.WriteLine("post1.Article：" + post1.Article);
                Console.WriteLine("post1 对应的状态：" + context.Entry(post1).State);

                context.Articles.Remove(article1);

                Console.WriteLine("\nRemove article1 之后");
                Console.WriteLine("post1.ArticleId：" + post1.ArticleId);
                Console.WriteLine("post1.Article：" + post1.Article);
                Console.WriteLine("post1 对应的状态：" + context.Entry(post1).State);

                context.SaveChanges();

                Console.WriteLine("\nSaveChanges之后");
                Console.WriteLine("post1.ArticleId：" + post1.ArticleId);
                Console.WriteLine("post1.Article：" + post1.Article);
                Console.WriteLine("post1 对应的状态：" + context.Entry(post1).State);
            }

            using (var context = new StudyContext())
            {
                Console.WriteLine("\n没有配置级联删除且外键能为空，删除主键模型，外键模型自动更新为NULL。\n");

                var catalog1 = context.Catalogs.First(x => x.Title == "Title1");
                var book1 = context.Books.First(x => x.Body == "Title1-Post");

                Console.WriteLine("Remove catalog1 之前");
                Console.WriteLine("book1.CatalogId：" + book1.CatalogId);
                Console.WriteLine("book1.Catalog：" + book1.Catalog);
                Console.WriteLine("post1 对应的状态：" + context.Entry(book1).State);

                context.Catalogs.Remove(catalog1);

                Console.WriteLine("\nRemove catalog1之后");
                Console.WriteLine("book1.CatalogId：" + book1.CatalogId);
                Console.WriteLine("book1.Catalog：" + book1.Catalog);
                Console.WriteLine("post1 对应的状态：" + context.Entry(book1).State);

                context.SaveChanges();

                Console.WriteLine("\nSaveChanges之后");
                Console.WriteLine("book1.CatalogId：" + book1.CatalogId);
                Console.WriteLine("book1.Catalog：" + book1.Catalog);
                Console.WriteLine("post1 对应的状态：" + context.Entry(book1).State);
            }

            // 在没有配置级联删除且外键不能为空的情况下，删除主键模型会失败，必须同时删除所有外键模型。
            using (var context = new StudyContext())
            {
                Console.WriteLine("\n没有配置级联删除且外键不能为空，删除主键模型时，如果不同时删除外键模型，删除会失败。\n");

                var newsType1 = context.NewsTypes.First(x => x.Title == "Title1");
                var news1 = context.News.First(x => x.Body == "Title1-Post");

                Console.WriteLine("Remove newsType1 之前");
                Console.WriteLine("news1.NewsTypeId：" + news1.NewsTypeId);
                Console.WriteLine("news1.NewsType：" + news1.NewsType);
                Console.WriteLine("news1 对应的状态：" + context.Entry(news1).State);

                context.NewsTypes.Remove(newsType1);

                Console.WriteLine("\nRemove newsType1 之后");
                Console.WriteLine("news1.NewsTypeId：" + news1.NewsTypeId);
                Console.WriteLine("news1.NewsType：" + news1.NewsType);
                Console.WriteLine("news1 对应的状态：" + context.Entry(news1).State);

                context.News.Remove(news1);

                Console.WriteLine("\nRemove news1 之后");
                Console.WriteLine("news1.NewsTypeId：" + news1.NewsTypeId);
                Console.WriteLine("news1.NewsType：" + news1.NewsType);
                Console.WriteLine("news1 对应的状态：" + context.Entry(news1).State);

                context.SaveChanges();

                Console.WriteLine("\nSaveChanges之后");
                Console.WriteLine("news1.NewsTypeId：" + news1.NewsTypeId);
                Console.WriteLine("news1.NewsType：" + news1.NewsType);
                Console.WriteLine("news1 对应的状态：" + context.Entry(news1).State);
            }
        }
    }
}
